home *** CD-ROM | disk | FTP | other *** search
- /* hash.c */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <malloc.h>
-
- #include "hash.h"
-
-
-
- static long HashSize;
- t_hash_table HashTable; /* static schlecht fuer MSC */
-
-
- static char *HashFileName = "symbols";
- static long MaxSearch; /* Suche nach freiem Platz in HashTable */
-
-
-
-
-
- /******************************************************************/
- /* Verwaltung Hashtabelle: INIT, SAVE, LOAD */
- /******************************************************************/
-
- void init_hashtable (void)
- {
- long i;
-
- /* HashSize berechnen: Primzahl < SZE_HASH_TABLE */
-
- HashSize = SZE_HASH_TABLE;
-
- /* Tabelle loeschen: */
-
- for (i=0; i<HashSize; i++)
- {
- HashTable[i].ident = NULL; /* Token frei */
- HashTable[i].type = 0;
- HashTable[i].flags = 0;
- HashTable[i].data = NULL;
- }
-
- MaxSearch = 0;
- }
-
- long save_hashtable (void)
- {
- long i, cnt = 0;
- FILE *fp;
-
- fp = fopen (HashFileName, "w");
- if (!fp)
- {
- fprintf( stderr, "error opening symbol file ");
- fprintf( stderr, "%s\n", HashFileName);
- }
-
- for (i=0; i<HashSize; i++)
- {
- if (HashTable[i].ident)
- {
- fprintf (fp, "%ld %ld %hd %s\n",
- i,
- HashTable[i].type,
- HashTable[i].flags,
- HashTable[i].ident );
- cnt++;
- }
- }
-
- fclose (fp);
-
- return (cnt);
- }
-
- long load_hashtable (void)
- {
- long i, dummy, cnt = 0;
- FILE *fp;
- char buf[200], str[5][100], *status;
-
- fp = fopen (HashFileName, "r");
- if (!fp)
- {
- fprintf( stderr, "error opening symbol file %s \n",
- HashFileName);
- }
-
- while (1)
- {
- status = fgets (buf, 199, fp);
- if (status == NULL) break;
-
- sscanf (buf, "%ld", &i);
-
- sscanf (buf, "%s%s%s%s%s", str[0], str[1], str[2],
- str[3], str[4] );
-
- HashTable[i].type = atoi (str[1]);
- HashTable[i].flags = (short) atoi (str[2]);
-
- HashTable[i].ident = malloc (strlen (str[4]) + 1); /* null char ! */
- if (HashTable[i].ident == NULL)
- fprintf(stderr, "error load_hashtable\n");
- strcpy (HashTable[i].ident, str[4]);
-
- cnt++;
- }
-
- fclose (fp);
-
- return (cnt);
- }
-
- long hash_search_steps (void)
- {
- return (MaxSearch);
- }
-
-
- /******************************************************************/
- /* Hash-Algorithmus (nicht optimiert): */
- /******************************************************************/
-
- static long hash (char *ident)
- {
- long i, s = 0;
-
- /* printf ("hash call '%s'\n", ident);
- */
- for (i=0; i<strlen(ident); i++)
- s += (unsigned char)ident[i];
- s *= 3;
-
- i = s % HashSize;
-
- if (i > HashSize) fprintf( stderr, "hash error\n");
-
- /* printf ("hash result: %ld\n", i);
- */
- return (i);
- }
-
-
- /******************************************************************/
- /* Zugriffe auf Hashtabelle: SEARCH, INSERT, UPDATE, GET, CLEAR */
- /******************************************************************/
-
- long search_token (char *ident, t_hash_data *data)
- {
- long index, index_old;
- short found = FALSE;
-
- if (!ident[0])
- {
- return (TOKEN_NOT_FOUND);
- }
-
- if (strlen (ident) >= SZE_HASH_IDENT)
- {
- fprintf(stderr, "hash warning: ident size overflow\n");
- ident [SZE_HASH_IDENT - 1] = 0;
- }
-
- index = hash (ident);
- index_old = index;
-
- if (!HashTable[index].ident)
- {
- return (TOKEN_NOT_FOUND);
- }
-
- /* Eintrag suchen: */
-
- found = FALSE;
-
- while (!found)
- {
- if (!HashTable[index].ident) break;
- else
- {
- if (strcmp (ident, HashTable[index].ident) == 0)
- {
- found = TRUE;
- break;
- }
- else
- {
- index++;
- if (index >= HashSize) index = 0;
- if (index == index_old) break;
- }
- }
- }
-
- /* printf (">%s< >%s< %ld %d\n", ident, HashTable[index].ident, index, found);
- */
-
- /* if (found)
- printf ("hash: data '%s' found (index = %d)\n", ident, index);
- else
- printf ("hash: data '%s' not found (index = %d)\n", ident, index);
- */
-
-
- if (found)
- {
- /* Hashtabelle lesen: */
-
- if( data )
- { strcpy (data->ident, HashTable[index].ident);
- data->type = HashTable[index].type;
- data->flags = HashTable[index].flags;
- data->data = HashTable[index].data;
- }
-
- return (index);
- }
- else
- return (TOKEN_NOT_FOUND);
- }
-
- long insert_token (t_hash_data *data)
- {
- long index, index_old, i = 0;
-
-
- if (strlen (data->ident) >= SZE_HASH_IDENT)
- {
- fprintf( stderr, "hash warning: ident size overflow\n");
- data->ident [SZE_HASH_IDENT - 1] = 0;
- }
-
- index = hash (data->ident);
- index_old = index;
-
- /* freien Platz suchen: */
-
- while (HashTable[index].ident)
- {
- index++;
- i++;
- if (index >= HashSize) index = 0;
- if (index == index_old)
- {
- fprintf( stderr, "hash error: hashtable full ! \n");
- exit (0);
- }
- }
-
- /* Anzahl der Suchschritte merken: */
-
- if (i > MaxSearch) MaxSearch = i;
-
-
- /* printf ("hash: token '%s' inserted (index = %d)\n", data->ident, index);
- */
- /* Eintrag in Hashtabelle: */
-
- HashTable[index].ident = malloc (sizeof(data->ident));
- strcpy (HashTable[index].ident, data->ident);
- HashTable[index].type = data->type;
- HashTable[index].flags = data->flags;
- HashTable[index].data = data->data;
-
- return (index);
- }
-
- void update_token (t_hash_data *data, long index)
- {
- if (index >= HashSize)
- {
- fprintf( stderr, "\nerror update_token: index overflow\n");
- exit (0);
- }
-
- /* Eintrag in Hashtabelle: */
-
- free (HashTable[index].ident);
- HashTable[index].ident = malloc (sizeof(data->ident));
- strcpy (HashTable[index].ident, data->ident);
- HashTable[index].type = data->type;
- HashTable[index].flags = data->flags;
- HashTable[index].data = data->data;
- }
-
- void get_token (t_hash_data *data, long index)
- {
- if (index >= HashSize)
- {
- fprintf( stderr, "\nerror get_token: index overflow\n");
- exit (0);
- }
-
- /* Hashtabelle lesen: */
-
- strcpy (data->ident, HashTable[index].ident);
- data->type = HashTable[index].type;
- data->flags = HashTable[index].flags;
- data->data = HashTable[index].data;
- }
-
- void clear_token (long index)
- {
- if (index >= HashSize)
- {
- fprintf( stderr, "\nerror clear_token: index overflow\n");
- exit (0);
- }
-
- free (HashTable[index].ident);
- HashTable[index].ident = malloc (8);
- strcpy (HashTable[index].ident, "!remvd!");
-
- /* es muss ein Eintrag stehen bleiben, sonst ist der schnelle
- Search-Algorithmus nicht mehr moeglich (Annahme lueckenloser
- Belegung der Tabelle ab hash(ident) !!) */
-
- HashTable[index].type = 0;
- HashTable[index].flags = 0;
- HashTable[index].data = NULL;
- }
-
- long create_token_id (void)
- {
- long i;
-
- /* Vergabe einer virtuellen Token-ID: */
-
- for (i=0; i<HashSize; i++)
- {
- if (HashTable[i].ident) continue;
-
- HashTable[i].ident = malloc (8);
- strcpy (HashTable[i].ident, "virtual");
-
- return (i);
- }
-
- fprintf( stderr, "hash error: hashtable full ! \n");
- exit (0);
- }
-
-
- /******************************************************************/
- /* Zugriffe auf Token-Flags: */
- /******************************************************************/
-
- void set_token_flag (long index, short flag)
- {
- if (index >= HashSize)
- {
- fprintf( stderr, "\nhash error: index overflow\n");
- exit (0);
- }
-
- HashTable[index].flags = flag;
- }
-
- short get_token_flag (long index)
- {
- return ((short) HashTable[index].flags);
- }
-
-
- char *get_symbol (long index)
- {
- static char str[20];
-
- /* Hashtabelle lesen: */
- if( index == TOKEN_NOT_FOUND )
- {
- sprintf (str, "<--??-->");
- return (str);
- }
- else if (!HashTable[index].ident)
- {
- sprintf (str, "#%ld", index);
- return (str);
- }
- else return (HashTable[index].ident);
- }
-